import { ts } from 'qvog-dsl';
import {
  CallExpression,
  native,
  HomeCheckHint
} from 'qvog-dsl';

const SEVERITY = 2;
const DOC_PATH = 'docs/path-traversal.md';
const DESCRIPTION = "Potential path traversal vulnerability: user-controlled input is used to construct file paths without validation. It is recommended to check for '../' or absolute paths before using the input.";

export default native<HomeCheckHint>()()
  .match(CallExpression)
  .when((node: ts.CallExpression) => {
    // 1. Match calls to fs.openSync, fs.readFileSync, fs.writeFileSync, etc.
    const funcExpr = node.expression;
    let funcName;
    if (ts.isPropertyAccessExpression(funcExpr)) {
      funcName = funcExpr.name.getText();

    }

    const fileFuncs = ['openSync', 'readFileSync', 'writeFileSync'];
    if (!fileFuncs.includes(funcName as string)) { return false };
    // 2. Check if the first argument is a binary expression (e.g., this.path + '/xxx')
    const firstArg = node.arguments[0];
    if (!firstArg || !ts.isBinaryExpression(firstArg)) { return false };

    // 3. Check if one part of the concatenation is user input, such as this.path or path (Identifier)
    const left = firstArg.left;
    return (
      ts.isPropertyAccessExpression(left) &&
      left.name.getText() === 'path'
    ) || (
        ts.isIdentifier(left) && left.getText() === 'path'
      );
  })
  .report({
    severity: SEVERITY,
    description: DESCRIPTION,
    docPath: DOC_PATH
  });
